package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"regexp"
	"strings"
	"sync"
	//"time"
	"word-replace/config"
	"word-replace/utils"
)

var wg sync.WaitGroup

func getPath() string {
	fmt.Println("请输入操作得路径：")
	pathReader := bufio.NewReader(os.Stdin)
	path, _ := pathReader.ReadString('\n')
	return path
}

func getFiles(path string, pathArr *[]string) {
	files, err := ioutil.ReadDir(strings.TrimSpace(path))
	if err != nil {
		fmt.Println("打开文件夹失败", err)
		return
	}
	for _, v := range files {
		//fmt.Println(k,v)
		if v.IsDir() {
			if utils.HasFileType(v.Name(), config.ExcludeDirs) {
				continue
			} else {
				getFiles(strings.TrimSpace(path)+"\\"+v.Name(), pathArr)
			}
		} else {
			if utils.HasFileType(v.Name(), config.FileTypes) {
				*pathArr = append(*pathArr, (strings.TrimSpace(path) + "\\" + v.Name()))
			}
		}
	}
}
func wordReplace(path string, count chan int) {
	fileObj, err := os.OpenFile(path, os.O_RDWR, 0644)
	if err != nil {
		fmt.Println("打开文件失败", err)
		return
	}
	defer fileObj.Close()
	var content []byte
	var b = make([]byte, 1024)
	for {
		n, err := fileObj.Read(b)
		if err == io.EOF {
			fmt.Println("文件读完了")
			break
		}
		if err != nil {
			fmt.Println("read file failed, err:", err)
			return
		}
		content = append(content, b[:n]...)
	}
	all := string(content)
	for k, v := range config.ReplaceRule {
		reg, err := regexp.Compile(k)
		if err != nil {
			fmt.Println(err)
			return
		}
		//fmt.Println(reg.MatchString(str2))
		all = reg.ReplaceAllString(all, v)
	}
	n, _ := fileObj.Seek(0, os.SEEK_END)
	_, err = fileObj.WriteAt([]byte(all), n)
	count <- 1
	fmt.Println(path + "   处理完了")
}
func main() {
	// 获取用户输入的路径
	path := getPath()
	// 所有待处理的文件路径
	files := make([]string, 0)
	// 递归文件夹下的所有文件和文件夹 符合条件的 放入通道
	getFiles(path, &files)
	//fmt.Println(files,"files")
	// 文件接收通道
	pathChan := make(chan string, 1)
	// 处理完毕通道
	countChan := make(chan int, 1)
	wg.Add(1)
	go func() {
		i := 0
		for k := range countChan {
			fmt.Println(k, "处理接收")
			i += k
			if i == len(files) {
				break
			}
		}
		close(countChan)
		wg.Done()
	}()
	// 开启 5个 goroutine 处理
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(i int) {
			for k := range pathChan {
				// 处理文件的逻辑
				fmt.Println(k, "文件路径")
				wordReplace(k, countChan)

			}
			wg.Done()
		}(i)
	}
	// 向通道中放入path
	for _, p := range files {
		pathChan <- p
	}
	close(pathChan)
	wg.Wait()
}
